package com.gmss.crawler.module.retraction.paper.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gmss.crawler.constants.Base;
import com.gmss.crawler.constants.Constants;
import com.gmss.crawler.enums.AcademicianEnum;
import com.gmss.crawler.enums.CommonEnum;
import com.gmss.crawler.module.integrity.integritycase.domain.IntegrityCase;
import com.gmss.crawler.module.publication.domain.Publication;
import com.gmss.crawler.module.retraction.company.domain.RCompany;
import com.gmss.crawler.module.retraction.company.service.IRCompanyService;
import com.gmss.crawler.module.retraction.paper.domain.RPaper;
import com.gmss.crawler.module.retraction.paper.service.IRPaperService;
import com.gmss.crawler.module.retraction.paperauthor.domain.RPaperAuthor;
import com.gmss.crawler.module.retraction.paperauthor.service.IRPaperAuthorService;
import com.gmss.crawler.module.retraction.reason.domain.RPaperReason;
import com.gmss.crawler.module.retraction.reason.service.IRPaperReasonService;
import com.gmss.crawler.module.title.domain.PersonTitle;
import com.gmss.crawler.service.RetractionPaperCrawlerService;
import com.gmss.crawler.utils.DateUtils;
import com.gmss.crawler.utils.ExcelUtils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 撤稿论文表 前端控制器
 * </p>
 *
 * @author Auto-generator
 * @since 2021-12-16
 */
@RestController
@RequestMapping("/rPaper")
public class RPaperController extends Base {

    @Resource
    private RetractionPaperCrawlerService retractionPaperCrawlerService;

    @Resource
    private IRPaperService iRPaperService;

    @Resource
    private IRPaperAuthorService irPaperAuthorService;

    @Resource
    private IRPaperReasonService iRPaperReasonService;

    @Resource
    private IRCompanyService iRCompanyService;


    /**
     * @param rPaper
     * @return
     */
    @PostMapping("/exportRPaperByExcel")
    public String exportRPaperByExcel(@RequestBody RPaperReqVo rPaper) {
        if (StringUtils.isBlank(rPaper.getFilePath()) || StringUtils.isBlank(rPaper.getFileName())) {
            return respJson(CommonEnum.PARAM_ERROR, "导出excel路径或excel名称不能为空！");
        }
        String fileName = rPaper.getFileName();
        String fileNamesuffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
        if (!StringUtils.equalsAny(fileNamesuffix, "xlsx", "xls")) {
            return respJson(CommonEnum.PARAM_ERROR, "导出excel的文件名称后缀不正确，后缀应该为xlsx或xls ");
        }

        final LambdaQueryWrapper<RPaper> lambda = new QueryWrapper<RPaper>().lambda();
        this.buildCondition(lambda, rPaper);
        List<RPaper> rPaperList = iRPaperService.list(lambda);
        List<Long> rPaperIdList = rPaperList.stream().map(RPaper::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(rPaperIdList)) {
            return respJson(CommonEnum.RESPONSE_CODE_EMPTY);
        }
        final LambdaQueryWrapper<RPaperReason> rPaperReasonlambda = new QueryWrapper<RPaperReason>().lambda();
        rPaperReasonlambda.in(RPaperReason::getRPaperId, rPaperIdList);
        List<RPaperReason> rPaperReasonList = iRPaperReasonService.list(rPaperReasonlambda);
        Map<Long, List<RPaperReason>> rPaperReasonMap = rPaperReasonList.stream().collect(Collectors.groupingBy(rPaperReason -> (rPaperReason.getRPaperId()), Collectors.toList()));
        iRPaperService.writeExcelTwo(rPaperList, rPaperReasonMap, rPaper.getFilePath(), rPaper.getFileName());
//        List<Map> authorAndCompanyList = irPaperAuthorService.queryRPaperAuthorAndCompany(rPaperIdList);
//        authorAndCompanyList.stream().collect(Collectors.groupingBy(map -> (map.get(""))))
        return respJson(CommonEnum.SUCCESS);
    }


    @PostMapping("exportRPaper")
    public String exportRPaper(@RequestBody String str) {
        if (StringUtils.isBlank(str))
            return respJson(CommonEnum.PARAM_NULL_ERROR);

        Map<String, Object> map = JSON.parseObject(str);
        if (MapUtils.isEmpty(map))
            return respJson(CommonEnum.PARAM_NULL_ERROR);

        if (!map.containsKey("filePath") || StringUtils.isBlank(map.get("filePath").toString())) {
            return respJson(CommonEnum.PARAM_ERROR, "导出excel的路径不能为空！");
        }

        if (!map.containsKey("fileName") || StringUtils.isBlank(map.get("fileName").toString())) {
            return respJson(CommonEnum.PARAM_ERROR, "导出excel的文件名称不能为空！");
        } else {
            String fileName = map.get("fileName").toString();
            String fileNamesuffix = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            if (!StringUtils.equalsAny(fileNamesuffix, "xlsx", "xls")) {
                return respJson(CommonEnum.PARAM_ERROR, "导出excel的文件名称后缀不正确，后缀应该为xlsx或xls ");
            }
        }
        List<RPaperAuthor> rPaperAuthorList = irPaperAuthorService.list();
        List<RPaperAuthor> authorList = new ArrayList<>();
        for (RPaperAuthor rPaperAuthor : rPaperAuthorList) {
            String rCompanyId = rPaperAuthor.getRCompanyId();
            String rCompanyName = "";
            if (StringUtils.contains(rCompanyId, ",")) {
                String[] companyId = rCompanyId.split(",");
                for (int i = 0; i < companyId.length; i++) {
                    RCompany rCompany = iRCompanyService.getById(companyId[i]);
                    if (i == 0) {
                        rCompanyName = rCompany.getCompanyName();
                    } else {
                        rCompanyName = rCompanyName + ";" + rCompany.getCompanyName();
                    }
                }
            } else {
                RCompany rCompany = iRCompanyService.getById(rCompanyId);
                if (rCompany != null) {
                    if (StringUtils.isNotBlank(rCompany.getCompanyName())) {
                        rCompanyName = rCompany.getCompanyName();
                    } else {
                        rCompanyName = "";
                    }
                }
            }
            rPaperAuthor.setRCompanyName(rCompanyName);
            authorList.add(rPaperAuthor);
        }
        boolean bool = iRPaperService.writeExcel(map.get("filePath").toString(), map.get("fileName").toString(), authorList);
        if (bool) {
            return respJson(CommonEnum.SUCCESS, "导出excel路径：" + map.get("filePath").toString() + File.separator + map.get("fileName").toString());
        } else {
            return respJson(CommonEnum.FAILURE);
        }
    }

    /**
     * 保存撤稿论文数据
     *
     * @return
     */
    @PostMapping("/saveRPaper")
    public String saveRPaper() {
        try {
            List<RPaper> rpaperList = retractionPaperCrawlerService.parseRetractionPaperHtmlData();
            if (CollectionUtils.isNotEmpty(rpaperList)) {
                LambdaQueryWrapper<RPaper> lambdaQueryWrapper = null;
                for (RPaper rPaper : rpaperList) {
                    lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    if (StringUtils.isNotBlank(rPaper.getRetractionOrOtherNoticesDoi()))
                        lambdaQueryWrapper.eq(RPaper::getRetractionOrOtherNoticesDoi, rPaper.getRetractionOrOtherNoticesDoi());
                    if (StringUtils.isNotBlank(rPaper.getOriginalDoi()))
                        lambdaQueryWrapper.eq(RPaper::getOriginalDoi, rPaper.getOriginalDoi());
                    lambdaQueryWrapper.eq(RPaper::getTitle, rPaper.getTitle());
                    lambdaQueryWrapper.eq(RPaper::getNatureOfNotice, rPaper.getNatureOfNotice());
                    int count = iRPaperService.count(lambdaQueryWrapper);
                    if (count > 0)
                        continue;
                    iRPaperService.save(rPaper);
                    if (CollectionUtils.isNotEmpty(rPaper.getReasonList())) {
                        List<RPaperReason> rPaperReasonList = new ArrayList<>();
                        for (String reason : rPaper.getReasonList()) {
                            RPaperReason rPaperReason = new RPaperReason().builder()
                                    .rPaperId(rPaper.getId())
                                    .reason(reason)
                                    .build();
                            rPaperReasonList.add(rPaperReason);
                        }
                        iRPaperReasonService.saveBatch(rPaperReasonList);
                    }
                }
            }
        } catch (Exception e) {
            log.error("saveRPaper Exception：{}", e);
            return respJson(CommonEnum.ERROR);
        }
        return respJson(CommonEnum.SUCCESS);
    }

    /**
     * 查询列表
     */
    @PostMapping("/list")
    public String list(@RequestBody RPaperReqVo rPaper) {
        final LambdaQueryWrapper<RPaper> lambda = new QueryWrapper<RPaper>().lambda();
        this.buildCondition(lambda, rPaper);
        return respJson(CommonEnum.SUCCESS, iRPaperService.list(lambda));
    }

    /**
     * 分页查询
     */
    @PostMapping("/page")
    public String page(@RequestBody RPaperReqVo pageParam) {
        final LambdaQueryWrapper<RPaper> lambda = new QueryWrapper<RPaper>().lambda();
        this.buildCondition(lambda, pageParam);
        final IPage<RPaper> page = iRPaperService.page(new Page<>(Constants.PAGE_NO, Constants.PAGE_SIZE), lambda);
        return respJson(CommonEnum.SUCCESS, page);
    }


    /**
     * 构造查询条件
     *
     * @param lambda
     * @param param
     */
    private void buildCondition(LambdaQueryWrapper<RPaper> lambda, RPaperReqVo param) {
        if (null != param.getId()) {
            lambda.eq(RPaper::getId, param.getId());
        }
        if (!StringUtils.isEmpty(param.getTitle())) {
            lambda.eq(RPaper::getTitle, param.getTitle());
        }
        if (!StringUtils.isEmpty(param.getOriginalPublicationDate())) {
            lambda.eq(RPaper::getOriginalPublicationDate, param.getOriginalPublicationDate());
        }
        if (!StringUtils.isEmpty(param.getOriginalPubMedId())) {
            lambda.eq(RPaper::getOriginalPubMedId, param.getOriginalPubMedId());
        }
        if (!StringUtils.isEmpty(param.getOriginalDoi())) {
            lambda.eq(RPaper::getOriginalDoi, param.getOriginalDoi());
        }
        if (!StringUtils.isEmpty(param.getRetractionOrOtherNoticesDate())) {
            lambda.eq(RPaper::getRetractionOrOtherNoticesDate, param.getRetractionOrOtherNoticesDate());
        }
        if (!StringUtils.isEmpty(param.getRetractionOrOtherNoticesPubMedId())) {
            lambda.eq(RPaper::getRetractionOrOtherNoticesPubMedId, param.getRetractionOrOtherNoticesPubMedId());
        }
        if (!StringUtils.isEmpty(param.getRetractionOrOtherNoticesDoi())) {
            lambda.eq(RPaper::getRetractionOrOtherNoticesDoi, param.getRetractionOrOtherNoticesDoi());
        }
        if (!StringUtils.isEmpty(param.getArticleType())) {
            lambda.eq(RPaper::getArticleType, param.getArticleType());
        }
        if (!StringUtils.isEmpty(param.getNatureOfNotice())) {
            lambda.eq(RPaper::getNatureOfNotice, param.getNatureOfNotice());
        }
        if (!StringUtils.isEmpty(param.getJournal())) {
            lambda.eq(RPaper::getJournal, param.getJournal());
        }
        if (!StringUtils.isEmpty(param.getPublisher())) {
            lambda.eq(RPaper::getPublisher, param.getPublisher());
        }
        if (!StringUtils.isEmpty(param.getSubject())) {
            lambda.eq(RPaper::getSubject, param.getSubject());
        }
        if (!StringUtils.isEmpty(param.getKeywords())) {
            lambda.eq(RPaper::getKeywords, param.getKeywords());
        }
        if (!StringUtils.isEmpty(param.getDescribeData())) {
            lambda.eq(RPaper::getDescribeData, param.getDescribeData());
        }
        if (!StringUtils.isEmpty(param.getRelatedLinks())) {
            lambda.eq(RPaper::getRelatedLinks, param.getRelatedLinks());
        }
        if (!CollectionUtils.isEmpty(param.getCreateTimeList())) {
            lambda.ge(RPaper::getCreateTime, param.getCreateTimeList().get(0));
            lambda.le(RPaper::getCreateTime, param.getCreateTimeList().get(1));
        }
        if (!StringUtils.isEmpty(param.getCreateUser())) {
            lambda.eq(RPaper::getCreateUser, param.getCreateUser());
        }
        if (!CollectionUtils.isEmpty(param.getUpdateTimeList())) {
            lambda.ge(RPaper::getUpdateTime, param.getUpdateTimeList().get(0));
            lambda.le(RPaper::getUpdateTime, param.getUpdateTimeList().get(1));
        }
        if (!StringUtils.isEmpty(param.getUpdateUser())) {
            lambda.eq(RPaper::getUpdateUser, param.getUpdateUser());
        }
        lambda.orderBy(true, false, RPaper::getId);
    }


    /**
     * 请求model
     */
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    private static class RPaperReqVo extends RPaper {
        private List<String> createTimeList; // 创建时间起止
        private List<String> updateTimeList; // 更新时间起止

    }


}
